home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
sos3-2.lha
/
src
/
cfe
/
cfe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-23
|
49KB
|
1,779 lines
/* --------------------------------------------------------------------------
* Copyright 1992 by Forschungszentrum Informatik (FZI)
*
* You can use and distribute this software under the terms of the licence
* you should have received along with this program.
* If not or if you want additional information, write to
* Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
* D-7500 Karlsruhe 1, Germany.
* --------------------------------------------------------------------------
*/
// **************************************************************************
// Module cfe Juergen Uhl (ju)
//
// **************************************************************************
// SOS schema compiler front end (cfe)
// **************************************************************************
#include <stdio.h>
#include <osfcn.h>
#include "sys.h"
#include "smg.h"
#include "cfe_err.h"
#include "trc_cfe.h"
#include "mta_use.h"
#include "cfe_yacc.h"
#include "cfe.h"
// EXPORT:
EXPORT sos_Schema_module cfe_schema;
EXPORT sos_Type_table cfe_type_tab;
EXPORT sos_Schema_type_List cfe_types;
EXPORT sos_Container cfe_cnt;
EXPORT sos_Int cfe_echo_flag = 0;
// LOCAL
LOCAL sos_Unidentified_type ERROR_TYPE;
LOCAL sos_Class_type make_aux_class_type (sos_Generic_instantiation gi,
sos_Schema_type_List type_decls);
LOCAL sos_Schema_type cfe_get_void_type();
LOCAL sos_Schema_type cfe_get_sos_Bool_type();
LOCAL sos_Schema_type cfe_get_sos_Int_type();
LOCAL sos_Schema_type cfe_get_sos_Eq_kind_type();
LOCAL sos_Schema_type cfe_get_container_type();
LOCAL void cfe_error (err_class ec, err_msg s, sos_String where);
LOCAL void copy_offsets_and_size (sos_Class_type, sos_Class_type);
LOCAL sos_Type_name subst_actual
(sos_Gen_param,
sos_Gen_param_List, sos_Type_name_List);
LOCAL sos_Super_class_List subst_super_classes
(sos_Super_class_List,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL void subst_methods
(sos_Method_List, sos_Class_type,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Bool must_subst_params
(sos_Param_List,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Param_List subst_params
(sos_Param_List,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Bool must_subst_type_name
(sos_Type_name,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Type_name subst_type_name
(sos_Type_name,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Bool must_subst_type_names
(sos_Type_name_List,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
LOCAL sos_Type_name_List subst_type_names
(sos_Type_name_List,
sos_Gen_param_List, sos_Type_name_List, sos_Schema_type_List);
EXPORT void cfe_compile()
{
T_PROC ("cfe_compile");
TT (cfe_H, T_ENTER);
ERROR_TYPE = sos_Unidentified_type::create (TEMP_CONTAINER);
ERROR_TYPE.set_name (smg_String ("__error").make_String (TEMP_CONTAINER));
yyparse();
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_init (sos_String name, sos_Imports imp)
{
T_PROC ("cfe_init");
TT (cfe_H, T_ENTER);
#if ! BOOT
smg_String n = name;
if (n.equal ("knl") OR
n.equal ("agg") OR
n.equal ("dir") OR
n.equal ("mta") OR
n.equal ("cci"))
cfe_error (err_USE, err_CFE_RESERVED_SCHEMA_NAME);
#endif
sos_Schema_module sm;
sos_String knlstr = smg_String ("knl").make_String (TEMP_CONTAINER);
if (NOT knlstr.equal (name))
{ sm = sos_Schema_module::lookup (knlstr);
if (sm == NO_OBJECT)
cfe_error (err_SYS, err_CFE_NO_KERNEL);
else if (NOT imp.is_element (sm))
{ imp.insert (1, sm);
sm.container().open (READING, WAITING);
}
}
knlstr.destroy();
// not yet implemented:
// open imported schemas (transitively) for reading
// open depending schemas (transitively) for writing
cfe_types = sos_Schema_type_List::create (cfe_cnt, FALSE);
cfe_type_tab = sos_String_sos_Schema_type_Mapping::create (cfe_cnt, FALSE, TRUE);
cfe_schema.set_has_external_types (FALSE);
cfe_schema.set_types (cfe_types);
cfe_schema.set_type_table (cfe_type_tab);
#ifdef BOOT
cfe_schema.install();
#endif
TT (cfe_H, T_LEAVE);
}
LOCAL sos_Bool cfe_set_predefined_method (sos_Bool is_local,
sos_Class_type ct,
smg_String n,
sos_Bool is_static,
sos_Param_List pl,
sos_Type_name rt)
{
T_PROC ("cfe_set_predefined_method");
TT (cfe_H, T_ENTER);
sos_Method_table mt;
sos_Method_List ml;
sos_Method m = sos_Method::create (cfe_cnt);
sos_Bool already_defined;
sos_String str = n.make_String(cfe_cnt);
if (is_local)
{ mt = ct.get_inherited_methods();
ml = mt [str];
already_defined = (ml != NO_OBJECT);
}
else
already_defined = FALSE;
m.set_name (str);
m.set_kind ((is_local) ? sos_PROTECTED
: sos_PUBLIC);
m.set_is_abstract (FALSE);
m.set_is_static (is_static);
m.set_is_operator (FALSE);
m.set_is_predefined (TRUE);
m.set_generated_from (sos_Method::make (NO_OBJECT));
m.set_params (pl);
m.set_result_type (rt);
m.set_impls (sos_Method_impl_List::make (NO_OBJECT));
if (already_defined) // implies 'is_local == TRUE'
{ if (mt.lookup (m) == NO_OBJECT OR ml.card() > 1)
cfe_error (err_USE, err_CFE_INVALID_LOCAL_METHOD, str);
str.destroy();
m.destroy();
agg_iterate (pl, sos_Param p)
{ p.destroy();
}
agg_iterate_end (pl, p);
pl.destroy();
}
else
{ m.set_defined_in (ct);
cfe_append_method (ct, m);
if (is_local)
mt.lookup_or_add (m);
}
TT (cfe_H, T_LEAVE);
return already_defined;
}
inline void cfe_set_predefined_public_method (sos_Class_type ct,
smg_String n,
sos_Bool is_static,
sos_Param_List pl,
sos_Type_name rt)
{ cfe_set_predefined_method (FALSE,ct,n,is_static,pl,rt);
}
inline sos_Bool cfe_set_predefined_local_method (sos_Class_type ct,
smg_String n,
sos_Param_List pl,
sos_Type_name rt)
{ return cfe_set_predefined_method (TRUE,ct,n,TRUE,pl,rt);
}
LOCAL void cfe_add_param (sos_Param_List pl,
smg_String n,
sos_Type_name tn,
sos_Expr de)
{
T_PROC ("cfe_add_param");
TT (cfe_H, T_ENTER);
sos_Param p = sos_Param::create (cfe_cnt);
p.set_name (n.make_String (cfe_cnt));
p.set_type_name (tn);
p.set_default_expr (de);
p.set_is_ref (FALSE);
pl.append (p);
TT (cfe_H, T_LEAVE);
}
LOCAL void cfe_set_predefined_methods (sos_Class_type ct)
{
T_PROC ("cfe_set_predefined_methods");
TT (cfe_H, T_ENTER);
sos_Param_List pl;
// create
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"_ct",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
sos_Param_List tail = ct.get_create_params();
if (tail != NO_OBJECT)
pl += tail;
cfe_set_predefined_public_method (ct,"create",TRUE,pl,ct);
// copy
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"o",ct,sos_Expr::make (NO_OBJECT));
cfe_add_param (pl,"cnt",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
cfe_set_predefined_public_method (ct,"copy",TRUE,pl,ct);
// clone
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"o",ct,sos_Expr::make (NO_OBJECT));
cfe_add_param (pl,"cnt",cfe_get_container_type(),sos_Expr::make (NO_OBJECT));
cfe_set_predefined_public_method (ct,"clone",TRUE,pl,ct);
// destroy
cfe_set_predefined_public_method (ct,"destroy",FALSE,
sos_Param_List::create (cfe_cnt),
cfe_get_void_type());
// assign
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"source",cfe_get_object_type(),sos_Expr::make (NO_OBJECT));
cfe_set_predefined_public_method (ct,"assign",FALSE,pl,cfe_get_void_type());
// equal
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"o",cfe_get_object_type(),sos_Expr::make (NO_OBJECT));
sos_Identifier id = sos_Identifier::create (cfe_cnt);
id.set_id (smg_String ("EQ_STRONG").make_String (cfe_cnt));
cfe_add_param (pl,"eq_kind",cfe_get_sos_Eq_kind_type(),id);
cfe_set_predefined_public_method (ct,"equal",FALSE,pl,
cfe_get_sos_Bool_type());
// hash_value
cfe_set_predefined_public_method (ct,"hash_value",FALSE,
sos_Param_List::create (cfe_cnt),
cfe_get_sos_Int_type());
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_init_methods (sos_Class_type ct)
{
T_PROC ("cfe_init_methods");
TT (cfe_H, T_ENTER);
ct.set_methods (sos_Method_List::create (cfe_cnt, FALSE));
ct.set_comp_methods (sos_Method_List::create (cfe_cnt, FALSE));
ct.set_static_methods (sos_Method_List::create (cfe_cnt, FALSE));
cfe_set_predefined_methods (ct);
ct.set_has_init_comps (FALSE);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_complete_methods (sos_Class_type ct)
{
T_PROC ("cfe_init_methods");
TT (cfe_H, T_ENTER);
sos_Param_List pl;
// local_assign
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
cfe_add_param (pl,"y",ct,sos_Expr::make (NO_OBJECT));
sos_Bool assign_defined
= cfe_set_predefined_local_method (ct,"local_assign",pl,
cfe_get_void_type());
// local_equal
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
cfe_add_param (pl,"y",ct,sos_Expr::make (NO_OBJECT));
sos_Identifier id = sos_Identifier::create (cfe_cnt);
id.set_id (smg_String ("EQ_STRONG").make_String (cfe_cnt));
cfe_add_param (pl,"eq_kind",cfe_get_sos_Eq_kind_type(),id);
sos_Bool equal_defined
= cfe_set_predefined_local_method (ct,"local_equal",pl,
cfe_get_sos_Bool_type());
// local_hash_value
pl = sos_Param_List::create (cfe_cnt);
cfe_add_param (pl,"x",ct,sos_Expr::make (NO_OBJECT));
sos_Bool hash_value_defined
= cfe_set_predefined_local_method (ct,"local_hash_value",pl,
cfe_get_sos_Int_type());
if (assign_defined AND NOT equal_defined)
cfe_error (err_WNG, err_CFE_ASSIGN_WITHOUT_EQUAL);
if (equal_defined AND NOT hash_value_defined)
cfe_error (err_WNG, err_CFE_EQUAL_WITHOUT_HASH);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_append_method (sos_Class_type ct, sos_Method m)
{
T_PROC ("cfe_append_method");
TT (cfe_H, T_ENTER);
if (m.get_is_static ())
ct.get_static_methods().append (m);
else if (m.has_type (sos_Comp_method_type))
ct.get_comp_methods().append (m);
else
ct.get_methods().append (m);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_append_comp_methods
(sos_Class_type ct,
sos_Type_name tn, sos_String name, sos_Expr init,
sos_Method_kind kind, sos_Method_kind set_kind,
sos_Bool is_value, sos_Bool is_local,
sos_Int &offset)
// Creates a new component method and append it to the appropriate
// method lists
{
T_PROC ("cfe_append_comp_method");
TT (cfe_H, T_ENTER);
sos_Type bt;
sos_String str;
sos_Comp_method cm;
sos_Param_List pl;
sos_Param pa;
smg_String s;
cm = sos_Comp_method::create (cfe_cnt);
s = smg_String ("get_") + name;
str = s.make_String (cfe_cnt);
cm.set_name (str);
cm.set_kind (kind);
cm.set_is_static (FALSE);
cm.set_is_operator (FALSE);
cm.set_is_predefined (FALSE);
cm.set_generated_from (sos_Method::make(NO_OBJECT));
cm.set_impls (sos_Method_impl_List::make (NO_OBJECT));
cm.set_defined_in (ct);
pl = sos_Param_List::create (cfe_cnt);
cm.set_params (pl);
cm.set_result_type (tn);
cm.set_init_expr (init);
cm.set_is_set (FALSE);
cm.set_is_value (is_value);
cm.set_is_local (is_local);
cm.set_offset (offset);
ct.get_comp_methods().append (cm);
if (NOT is_value)
{ cm = sos_Comp_method::create (cfe_cnt);
s = smg_String ("set_") + name;
str = s.make_String (cfe_cnt);
cm.set_name (str);
cm.set_kind (set_kind);
cm.set_is_static (FALSE);
cm.set_is_operator (FALSE);
cm.set_is_predefined (FALSE);
cm.set_generated_from (sos_Method::make(NO_OBJECT));
cm.set_impls (sos_Method_impl_List::make (NO_OBJECT));
cm.set_defined_in (ct);
pa = sos_Param::create (cfe_cnt);
pa.set_name (sos_String::make (NO_OBJECT));
pa.set_type_name (tn);
pa.set_default_expr (sos_Expr::make (NO_OBJECT));
pa.set_is_ref (FALSE);
pl = sos_Param_List::create (cfe_cnt, FALSE);
pl.append (pa);
cm.set_params (pl);
cm.set_result_type (cfe_get_void_type());
cm.set_init_expr (init);
cm.set_is_set (TRUE);
cm.set_is_value (is_value);
cm.set_is_local (is_local);
cm.set_offset (offset);
ct.get_comp_methods().append (cm);
}
bt = tn.make_base_type();
if (bt != NO_OBJECT AND bt.is_scalar())
offset += bt.get_object_size();
else if (is_local)
offset += SOS_OFFSET_SIZE;
else
offset += SOS_TYPED_ID_SIZE;
TT (cfe_H, T_LEAVE);
}
LOCAL void cfe_commit_schema()
// Enter the current schema module into the schema table and close/commit
// the schema container together with the schema table container.
{
T_PROC ("cfe_commit_schema");
TT (cfe_H, T_ENTER);
#ifndef BOOT
cfe_schema.install();
#endif
cfe_cnt.close();
TT (cfe_H, T_LEAVE);
}
LOCAL void cfe_reset_schema()
// Destroy the current schema container.
{
T_PROC ("cfe_reset_schema");
TT (cfe_H, T_ENTER);
cfe_cnt.destroy();
cfe_cnt.close();
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_finalize()
{
T_PROC ("cfe_finalize");
TT (cfe_H, T_ENTER);
cfe_schema.close_imports();
if (err_occurred (err_SYS) + err_occurred (err_USE) == 0)
cfe_commit_schema();
else
cfe_reset_schema();
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_check_schema ()
{
T_PROC ("cfe_check_schema");
TT (cfe_H, T_ENTER);
agg_iterate_association (cfe_type_tab, sos_String name, sos_Schema_type tp)
{ if (tp.has_type (sos_Forward_class_type_type))
cfe_error (err_USE, err_CFE_NOT_DECLARED, tp.get_name());
}
agg_iterate_association_end (cfe_type_tab, name, tp);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_check_super_classes (sos_Class_type ct, sos_Type_name_List tnl)
// Checks the correct use of super classes given in list 'tnl'. A class
// specified as super class of any other class must be declared before.
{
T_PROC ("cfe_check_super_classes");
TT (cfe_H, T_ENTER);
sos_Cursor c = tnl.open_cursor();
for (sos_Bool valid = tnl.is_valid (c); valid;)
{ sos_Type_name tn = tnl.get(c);
sos_Bool error = FALSE;
if (tn.has_type (sos_Gen_param_type))
{ cfe_error (err_USE, err_CFE_UNDECL_CLASS, tn.make_type_name());
error = TRUE;
}
else
{ sos_Type bt = tn.make_base_type();
if (bt == NO_OBJECT)
error = TRUE;
else if (bt.has_type (sos_Class_type_type))
{ sos_Class_type sct = sos_Class_type::make(bt);
// check for "class A : A"
#ifdef ATT
if (ct.operator==(sct))
#else
if (ct == sct)
#endif
{ cfe_error (err_USE, err_CFE_UNDECL_CLASS, tn.make_type_name());
error = TRUE;
}
// check create parameters
sos_Param_List fpl = sct.get_create_params();
sos_Expr_List apl;
sos_Int fc, ac;
if (tn.has_type (sos_Type_with_params_type))
{ apl = sos_Type_with_params::make (tn).get_params();
ac = apl.card();
}
else
{ apl = sos_Expr_List::make (NO_OBJECT);
ac = 0;
}
if (fpl == NO_OBJECT)
fc = 0;
else
fc = fpl.card();
if (fc < ac)
{ cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
tn.make_type_name());
error = TRUE;
}
else
{ sos_Bool has_defaults = TRUE;
for (ac++; ac <= fc; ac++)
{ if (fpl.get_nth (ac).get_default_expr() == NO_OBJECT)
{ has_defaults = FALSE;
break;
}
}
if (NOT has_defaults)
{ cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
tn.make_type_name());
error = TRUE;
}
}
}
else
{ cfe_error (err_USE, err_CFE_CLASS_EXPECTED, tn.make_type_name());
error = TRUE;
}
}
if (error)
{ tnl.remove_at(c);
valid = tnl.is_valid(c);
}
else
valid = tnl.to_succ(c);
}
tnl.close_cursor (c);
}
LOCAL sos_Bool super_class_in_list (sos_Super_class_List scl, sos_Type tp)
{
T_PROC ("super_class_in_list");
TT (cfe_H, T_ENTER);
sos_Bool found = FALSE;
agg_iterate (scl, sos_Super_class sc)
{ if (sc.get_super_class().identical(tp))
{ found = TRUE;
break;
}
}
agg_iterate_end (scl, sc);
TT (cfe_H, T_LEAVE);
return found;
}
LOCAL sos_Expr_List formal_params_to_actuals (sos_Param_List fpl)
{
T_PROC ("formal_params_to_actuals");
TT (cfe_H, T_ENTER);
sos_Expr_List result;
if (fpl == NO_OBJECT)
result = sos_Expr_List::make (NO_OBJECT);
else
{ result = sos_Expr_List::create (cfe_cnt);
agg_iterate (fpl, sos_Param fp)
{ sos_Identifier id = sos_Identifier::create (cfe_cnt);
id.set_id (fp.get_name());
result.append (id);
}
agg_iterate_end (fpl, fp);
}
TT (cfe_H, T_LEAVE);
return result;
}
LOCAL sos_Expr_List expand_params (sos_Expr_List original,
sos_Param_List fpl,
sos_Expr_List apl)
// class A (f1, ..., fm) : ... C (o1, ..., on) ...
// class B : ... A (a1, ..., am) ...
// result : subst fi through ai in oi
{
T_PROC ("expand_params");
TT (cfe_H, T_ENTER);
sos_Expr_List result;
if (original == NO_OBJECT || fpl == NO_OBJECT)
result = original;
else
{ result = sos_Expr_List::create (cfe_cnt);
agg_iterate (original, sos_Expr expr)
{ sos_Expr subst = expr;
if (expr.has_type (sos_Identifier_type))
{ sos_String id = sos_Identifier::make (expr).get_id();
sos_Bool av = apl != NO_OBJECT;
sos_Cursor c;
if (av)
{ c = apl.open_cursor();
av = apl.is_valid (c);
}
agg_iterate (fpl, sos_Param fp)
{ sos_String s = fp.get_name();
if (s != NO_OBJECT AND s.equal (id))
{ if (av)
subst = apl.get(c);
else
subst = fp.get_default_expr();
break;
}
if (av) av = apl.to_succ (c);
}
agg_iterate_end (fpl, fp);
if (apl != NO_OBJECT)
apl.close_cursor (c);
}
result.append (subst);
}
agg_iterate_end (original, expr);
}
TT (cfe_H, T_LEAVE);
return result;
}
LOCAL void append_super_class (sos_Super_class_List scl,
sos_Class_type ct,
sos_Expr_List cpl)
{
T_PROC ("append_super_class");
TT (cfe_H, T_ENTER);
sos_Super_class sc = sos_Super_class::create (cfe_cnt);
sc.set_super_class (ct);
sc.set_create_params (cpl);
scl.append (sc);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_set_super_closure (sos_Class_type ct)
// compute super closure in prefix order using the already
// computed super closure of the super classes of ct.
// (i.e. a superclass appears always before any of its subclasses
// in the Super_class_List)
{
T_PROC ("cfe_set_super_closure");
TT (cfe_H, T_ENTER);
sos_Param_List fcp = ct.get_create_params ();
sos_Type_name_List tnl = ct.get_super_classes();
sos_Super_class_List new_scl = sos_Super_class_List::create (cfe_cnt, FALSE);
agg_iterate (tnl, sos_Type_name tn)
{
sos_Type bt = tn.make_base_type();
if (bt.has_type (sos_Class_type_type) AND
NOT super_class_in_list (new_scl, bt))
{
sos_Class_type ct1 = sos_Class_type::make (bt);
sos_Super_class_List scl1 = ct1.get_super_closure();
sos_Param_List fcp1 = ct1.get_create_params();
sos_Expr_List acp1 = tn.create_params();
agg_iterate (scl1, sos_Super_class sc2)
{
sos_Class_type ct2 = sc2.get_super_class();
if (NOT super_class_in_list (new_scl, ct2))
{
sos_Expr_List acp2 = sc2.get_create_params();
append_super_class (new_scl, ct2,
expand_params (acp2, fcp1, acp1));
}
}
agg_iterate_end (scl1, sc2);
}
}
agg_iterate_end (tnl, tn);
append_super_class (new_scl, ct, formal_params_to_actuals (fcp));
// the super_closure contains the class itself!
ct.set_super_closure (new_scl);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_set_offsets_and_size (sos_Class_type ct, sos_Int os)
{
T_PROC ("cfe_set_offsets_and_size");
TT (cfe_H, T_ENTER);
ct.set_local_size (os);
sos_Int offset = 0;
sos_Super_class_List scl = ct.get_super_closure();
agg_iterate (scl, sos_Super_class sc)
{ sc.set_offset(offset);
offset += sc.get_super_class().get_local_size();
}
agg_iterate_end (scl, sc);
ct.set_object_size (offset);
TT (cfe_H, T_LEAVE);
}
LOCAL void insert_methods (sos_Method_table mt, sos_Method_List ml)
{
T_PROC ("insert_methods");
TT (cfe_M, T_ENTER);
agg_iterate (ml, sos_Method m)
{ sos_Method m1 = mt.lookup_or_add (m);
#ifdef ATT
if (m1.operator!=(m))
#else
if (m1 != m)
#endif
cfe_error (err_USE, err_CFE_INVALID_OVERLOADING, m.get_name());
}
agg_iterate_end (ml, m);
TT (cfe_M, T_LEAVE);
}
LOCAL sos_Bool dominates (sos_Method m, sos_Method m1)
// class of m derived from class of m1
{
T_PROC ("dominates");
TT (cfe_M, T_ENTER);
sos_Bool result = m.get_defined_in().is_derived_from_some
(m1.get_defined_in().root_class());
TT (cfe_M, T_LEAVE);
return result;
}
EXPORT void cfe_set_inherited_methods (sos_Class_type ct)
// This function yields all methods that are inherited from class "ct" by
// its super classes and the operators of class "ct" itself.
{
T_PROC ("cfe_set_inherited_methods");
TT (cfe_H, T_ENTER);
sos_Method_table mt = sos_Method_table::create (cfe_cnt);
insert_methods (mt, ct.get_methods());
insert_methods (mt, ct.get_comp_methods());
insert_methods (mt, ct.get_static_methods());
sos_Type_name_List super_classes = ct.get_super_classes();
agg_iterate (super_classes, sos_Type_name stn)
{ sos_Class_type super_class = sos_Class_type::make(stn.make_base_type());
sos_Method_table scmt = super_class.get_inherited_methods();
agg_iterate_association (scmt, sos_String name, sos_Method_List ml)
{ agg_iterate (ml, sos_Method m)
{ if (m.get_kind() != sos_PRIVATE AND NOT m.get_is_static())
{ sos_Method m1 = mt.lookup_or_add (m);
#ifdef ATT
if (m1.operator!=(m))
#else
if (m1 != m)
#endif
{ // m1 - a different method with the same name as m found
// m1 doesn't overload m!
if (dominates (m1, m))
{
#ifdef ATT
if (ct.operator== (m1.get_defined_in()))
#else
if (ct == m1.get_defined_in())
#endif
{ if (m1.redefines (m))
{ if (m1.get_generated_from () == NO_OBJECT)
m1.set_generated_from (m.get_generated_from());
}
else // m1 defined in the given class
// and no redefinition
cfe_error (err_USE, err_CFE_INVALID_REDEFINITION,
m.get_name());
}
}
else if (dominates (m, m1))
mt.replace_or_add (m);
else
cfe_error (err_USE, err_CFE_AMBIGUOUS_METHODS,
m.get_name());
}
}
}
agg_iterate_end (ml, m);
}
agg_iterate_association_end (scmt, name, ml);
}
agg_iterate_end (super_classes, super_class);
ct.set_inherited_methods (mt);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_set_root_name (sos_Class_type ct)
{
T_PROC ("cfe_set_root_name");
TT (cfe_H, T_ENTER);
sos_Gen_param_List gpl = ct.get_gen_params();
if (gpl != NO_OBJECT)
{ smg_String s = "";
agg_iterate (gpl, sos_Gen_param gp)
{ s += gp.make_type_name();
s += "_";
}
agg_iterate_end (gpl, gp);
s += ct.get_name();
sos_String rn = s.make_String (cfe_cnt);
ct.set_root_name (rn);
cfe_type_tab.insert (rn, ct);
}
else
ct.set_root_name (sos_String::make (NO_OBJECT));
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_check_type (sos_String t_name)
// Checks multiple declarations of type names
{
T_PROC ("cfe_check_type");
TT (cfe_H, T_ENTER);
sos_Type t = cfe_schema.lookup_type (t_name);
if (t != NO_OBJECT)
cfe_error (err_USE, err_CFE_MULTIPLE_TYPE_DECL, t_name);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_make_class_type (sos_String name, sos_Class_type ct)
// Checks multiple declarations of type names
{
T_PROC ("cfe_check_class_type");
TT (cfe_H, T_ENTER);
sos_Type t = cfe_schema.lookup_type (name);
if (t.has_type (sos_Forward_class_type_type))
{ sos_Forward_class_type fwt = sos_Forward_class_type::make(t);
fwt.set_complete (ct);
}
else if (t != NO_OBJECT)
cfe_error (err_USE, err_CFE_MULTIPLE_TYPE_DECL, name);
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_check_no_generic (sos_Type_name tn)
{
T_PROC ("cfe_check_no_generic");
TT (cfe_H, T_ENTER);
if (tn.has_type (sos_Class_type_type))
{ sos_Class_type ct = sos_Class_type::make (tn);
if (ct.get_gen_params() != NO_OBJECT)
cfe_error (err_USE, err_CFE_NO_GENERIC_TYPE, ct.get_name());
}
TT (cfe_H, T_LEAVE);
}
EXPORT void cfe_error (err_class ec, err_msg s, char* where /* = 0 */)
{
T_PROC ("cfe_error");
TT (cfe_H, T_ENTER);
smg_String line_msg = smg_String ("line ") + yylineno;
if (where)
line_msg += smg_String(": ") + where;
err_raise (ec, s, line_msg.make_Cstring (SMG_BORROW));
TT (cfe_H, T_LEAVE);
}
LOCAL void cfe_error (err_class ec, err_msg s, sos_String where)
{ sos_Cstring w = where.make_Cstring();
cfe_error (ec, s, w);
delete w;
}
EXPORT void cfe_import_module (sos_Imports imp, sos_String name)
// Check existence of a schema module named 'name' and append it
// at the module list imp
{
T_PROC ("cfe_import_module");
sos_Schema_module sm;
sm = sos_Schema_module::lookup (name);
if (sm == NO_OBJECT)
cfe_error (err_USE, err_CFE_INVALID_IMPORT, name);
else
imp.append (sm);
}
EXPORT sos_Type_name cfe_lookup_type_name (sos_Class_type ct, sos_String name)
{
T_PROC ("cfe_lookup_type_name");
TT (cfe_H, T_ENTER);
if (ct != NO_OBJECT)
{ sos_Gen_param_List gpl = ct.get_gen_params();
if (gpl != NO_OBJECT)
{ sos_Gen_param gp = cfe_lookup_gen_params (name, gpl);
if (gp != NO_OBJECT)
{ TT (cfe_H, T_LEAVE);
return gp;
}
}
}
sos_Schema_type tp = cfe_schema.lookup_type (name);
if (NOT tp.identical (NO_OBJECT))
{ TT (cfe_H, T_LEAVE);
return tp;
}
else
{ sos_String n = sos_String::copy (name, cfe_cnt);
sos_Forward_class_type fw = sos_Forward_class_type::create (cfe_cnt);
fw.set_name (n);
fw.set_complete (sos_Class_type::make (NO_OBJECT));
cfe_type_tab.insert (n, fw);
cfe_types.append (fw);
return fw;
}
}
EXPORT sos_Type_name cfe_lookup_generic_instantiation
(sos_String gen_class_name,
sos_Type_name_List agpl,
sos_Schema_type_List type_decls)
{
T_PROC ("cfe_lookup_generic_instantiation");
TT (cfe_H, T_ENTER);
sos_Type t = cfe_schema.lookup_type (gen_class_name);
if (t.identical (NO_OBJECT))
{ cfe_error (err_USE, err_CFE_UNKNOWN_TYPE, gen_class_name);
return ERROR_TYPE;
}
else if (t.has_type (sos_Forward_class_type_type))
{ cfe_error (err_USE, err_CFE_UNDECL_CLASS, gen_class_name);
return ERROR_TYPE;
}
else if (NOT t.has_type (sos_Class_type_type))
{ cfe_error (err_USE, err_CFE_CLASS_EXPECTED, gen_class_name);
return ERROR_TYPE;
}
else
{ sos_Class_type gt = sos_Class_type::make(t);
sos_Gen_param_List fgpl = gt.get_gen_params();
if (fgpl == NO_OBJECT)
{ cfe_error (err_USE, err_CFE_GENERIC_TYPE_EXPECTED, gen_class_name);
return ERROR_TYPE;
}
else if (fgpl.card() != agpl.card())
{ cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH, gen_class_name);
return ERROR_TYPE;
}
else
{ sos_Generic_instantiation gi =
sos_Generic_instantiation::create(cfe_cnt);
gi.set_gen(gt);
gi.set_gen_params(agpl);
gi.set_instantiation (make_aux_class_type (gi, type_decls));
return gi;
}
}
}
EXPORT void cfe_check_generic_instantiations (sos_Type_name_List tnl)
{ agg_iterate (tnl, sos_Type_name tn)
{ if (tn.has_type (sos_Generic_instantiation_type))
{ sos_Generic_instantiation gi = sos_Generic_instantiation::make (tn);
sos_Type_name_List agpl = gi.get_gen_params();
sos_Class_type gt = gi.get_gen();
sos_Gen_param_List fgpl = gt.get_gen_params();
agg_iterate_double (agpl, sos_Type_name agp,
fgpl, sos_Gen_param fgp, sos_Int comp)
{ if (fgp.get_super_class() != NO_OBJECT AND
NOT agp.make_type().is_derived_from (fgp.make_type()))
{ smg_String s = smg_String (gt.get_name()) + "<...," +
agp.make_type_name() + ",...>";
cfe_error (err_USE, err_CFE_GEN_PARAM_MISMATCH,
s.make_Cstring (SMG_BORROW));
}
}
agg_iterate_double_end (agpl, agp, fgpl, fgp, comp);
}
}
agg_iterate_end (tnl, tn);
}
EXPORT sos_Gen_param cfe_lookup_gen_params (sos_String name,
sos_Gen_param_List gpl)
// Search for a generic parameter 'name' in the generic parameter list 'gpl'.
// Return the generic parameter found if any or NO_OBJECT otherwise.
{
T_PROC ("cfe_lookup_gen_params");
TT (cfe_H, T_ENTER);
sos_Gen_param result;
sos_Bool found = FALSE;
agg_iterate (gpl, sos_Gen_param gp)
{ if (name.equal (gp.get_name()))
{ found = TRUE;
result = gp;
break;
}
}
agg_iterate_end (gpl, gp);
if (NOT found)
result = sos_Gen_param::make (NO_OBJECT);
TT (cfe_H, T_LEAVE; TB(found))
return result;
}
EXPORT sos_Int cfe_enum_size (sos_Int nr_literals)
{ if (nr_literals <= 256)
return 1;
else if (nr_literals <= 65536)
return 2;
else
cfe_error (err_USE, err_CFE_TOO_MANY_LITERALS);
return 0;
}
LOCAL sos_String instantiation_name (sos_Generic_instantiation gi,
sos_Bool base_name)
{
T_PROC ("instantiation_name");
TT (cfe_M, T_ENTER);
sos_Type_name_List tnl = gi.get_gen_params();
smg_String s = "";
agg_iterate (tnl, sos_Type_name tn)
{ sos_String ts;
if (base_name)
ts = tn.make_base_type().make_type_name();
else
ts = tn.make_type_name();
s += ts;
s += "_";
}
agg_iterate_end (tnl, tn);
s += gi.get_gen().get_name();
TT (cfe_M, T_LEAVE);
return s.make_String (TEMP_CONTAINER);
}
LOCAL sos_Class_type make_aux_class_type (sos_Generic_instantiation gi,
sos_Schema_type_List type_decls)
// Generates new class types by substituting the actual types of
// generic instantiation 'gi' within the corresponding generic class
// declaration. However, class instantiation 'gi' will be evaluated only if
// it is no universal instance, i.e. none of its actual types is a generic
// parameter. The created class types are inserted into type table
// 'cfe_type_tab', respectively appended at the list of output type declarations
// 'type_decls'. If 'gi' = C<T1,...,Tn> then a new class type with
// name T1'_..._Tn'_C is created where Ti' is the base name of type Ti
// (i.e typedef's are evaluated (see function 'instantiation_name')).
// Note that the substitution of types Ti in the declaration of generic
// class C may lead to a recursive call of 'make_aux_class_type' due to
// the evaluation of class instances within the C-declaration.
{
T_PROC ("make_aux_class_type");
TT (cfe_M, T_ENTER);
sos_Class_type aux_c;
sos_Class_type g = gi.get_gen();
sos_String base_name = instantiation_name (gi, TRUE);
if (gi.is_universal())
aux_c = gi.get_gen();
else
{ sos_Type tp = cfe_schema.lookup_type (base_name);
if (tp == NO_OBJECT)
{ sos_Gen_param_List gen_params = g.get_gen_params();
sos_Type_name_List act_params = gi.get_gen_params();
sos_String bn = sos_String::copy (base_name, cfe_cnt);
aux_c = sos_Class_type::create (cfe_cnt);
aux_c.set_generated_from (gi);
aux_c.set_name(bn);
aux_c.set_super_classes (subst_type_names
(g.get_super_classes(), gen_params, act_params, type_decls));
// IMPORTANT: generated class type must be inserted into the type
// table after(!) the evaluation of its super_classes
// and before(!) the replacement of the actual parameters
// in the body of the class
cfe_type_tab.insert (bn, aux_c);
type_decls.append (aux_c);
if (g.get_create_params() == NO_OBJECT)
aux_c.set_create_params (sos_Param_List::make (NO_OBJECT));
else
{ sos_Param_List new_pl = subst_params
(g.get_create_params(), gen_params, act_params, type_decls);
aux_c.set_create_params (new_pl);
}
cfe_set_super_closure (aux_c);
copy_offsets_and_size (aux_c, g);
aux_c.set_friends (subst_type_names
(g.get_friends(), gen_params, act_params, type_decls));
cfe_init_methods (aux_c);
subst_methods (g.get_methods(), aux_c,
gen_params, act_params, type_decls);
subst_methods (g.get_comp_methods(), aux_c,
gen_params, act_params, type_decls);
subst_methods (g.get_static_methods(), aux_c,
gen_params, act_params, type_decls);
aux_c.set_has_init_comps (g.get_has_init_comps());
cfe_set_inherited_methods (aux_c);
cfe_complete_methods (aux_c);
}
else if (tp.has_type (sos_Class_type_type))
aux_c = sos_Class_type::make (tp);
else // error
aux_c = sos_Class_type::make (NO_OBJECT);
}
sos_String name = instantiation_name (gi, FALSE);
if (NOT base_name.equal (name) AND cfe_schema.lookup_type (name) == NO_OBJECT)
{
// In order to allow the use of 'name' in the application program
// generate a typedef of the form "typedef base_name name;" .
// Example: SOS declarations
//
// typedef sos_Int T;
// class C1<X> { ... X ... };
// class C2 { ... C1<T> ... } generate
//
// typedef sos_Int T;
// class C1 { ... sos_Object ... };
// class sos_Int_C { ... sos_Int ... };
// typedef sos_Int_C T_C; !!
// class C2 { ... T_C ... };
sos_Typedef_type aux_td = sos_Typedef_type::create (cfe_cnt);
sos_String n = sos_String::copy (name, cfe_cnt);
aux_td.set_name (n);
aux_td.set_type_name (aux_c);
cfe_type_tab.insert (n, aux_td);
type_decls.append (aux_td);
}
TT (cfe_M, T_LEAVE);
return aux_c;
}
LOCAL void copy_offsets_and_size (sos_Class_type ct1, sos_Class_type ct2)
{
T_PROC ("copy_offsets_and_size");
TT (cfe_M, T_ENTER);
ct1.set_local_size (ct2.get_local_size());
sos_Super_class_List scl1 = ct1.get_super_closure();
sos_Super_class_List scl2 = ct2.get_super_closure();
if (scl1.card() != scl2.card())
err_raise (err_SYS, err_CFE_SCRAMBLED_INSTANTIATION, NULL, FALSE);
agg_iterate_double (scl1, sos_Super_class sc1,
scl2, sos_Super_class sc2, sos_Int comp)
{
#ifdef ATT
if (sc1.get_super_class().root_class().operator!=
(sc2.get_super_class().root_class()))
#else
if (sc1.get_super_class().root_class() !=
sc2.get_super_class().root_class())
#endif
err_raise (err_SYS, err_CFE_SCRAMBLED_INSTANTIATION, NULL, FALSE);
sc1.set_offset (sc2.get_offset());
}
agg_iterate_double_end (scl1, sc1, scl2, sc2, comp);
ct1.set_object_size (ct2.get_object_size());
TT (cfe_M, T_LEAVE);
}
LOCAL sos_Type_name subst_actual (sos_Gen_param gp,
sos_Gen_param_List gpl,
sos_Type_name_List tnl)
{
T_PROC ("subst_actual");
TT (cfe_M, T_ENTER);
sos_Type_name tn;
sos_Bool found = FALSE;
agg_iterate_double (gpl, sos_Gen_param gp1,
tnl, sos_Type_name tn1, sos_Int comp)
{ if (gp.identical (gp1))
{ tn = tn1; found = TRUE; break; }
}
agg_iterate_double_end (gpl, gp1, tnl, tn1, comp);
if (NOT found)
{ cfe_error (err_SYS, err_CFE_INTERNAL);
tn = sos_Type_name::make (NO_OBJECT);
}
TT (cfe_M, T_LEAVE; TB(found));
return tn;
}
LOCAL sos_Method subst_method (sos_Method old,
sos_Class_type aux_c,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("subst_method");
TT (cfe_M, T_ENTER);
sos_Param_List old_pl = old.get_params();
sos_Param_List new_pl = subst_params (old_pl, gpl, tnl, type_decls);
sos_Type_name old_tn = old.get_result_type();
sos_Type_name new_tn = subst_type_name (old_tn, gpl, tnl, type_decls);
sos_Method new_m;
#ifdef ATT
if (new_pl.operator==(old_pl) AND new_tn.operator==(old_tn))
#else
if (new_pl == old_pl AND new_tn == old_tn)
#endif
new_m = old;
else
{ if (old.has_type (sos_Comp_method_type))
{ sos_Comp_method cm = sos_Comp_method::make (old);
sos_Comp_method new_cm = sos_Comp_method::create (cfe_cnt);
new_cm.set_is_set (cm.get_is_set());
new_cm.set_is_value (cm.get_is_value());
new_cm.set_is_local (cm.get_is_local());
new_cm.set_offset (cm.get_offset());
new_m = new_cm;
}
else
new_m = sos_Method::create (cfe_cnt);
new_m.set_kind (old.get_kind());
new_m.set_name (old.get_name());
new_m.set_generated_from (old);
new_m.set_impls (sos_Method_impl_List::make (NO_OBJECT));
new_m.set_defined_in (aux_c);
new_m.set_is_static (old.get_is_static());
new_m.set_is_operator (old.get_is_operator());
new_m.set_is_predefined (old.get_is_predefined());
new_m.set_params (new_pl);
new_m.set_result_type (new_tn);
}
TT (cfe_M, T_LEAVE);
return new_m;
}
LOCAL void subst_methods (sos_Method_List old,
sos_Class_type aux_c,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("subst_methods");
TT (cfe_M, T_ENTER);
agg_iterate (old, sos_Method old_m)
{ if (NOT old_m.get_is_predefined())
cfe_append_method
(aux_c, subst_method (old_m, aux_c, gpl, tnl, type_decls));
}
agg_iterate_end (old, old_m);
TT (cfe_M, T_LEAVE);
}
LOCAL sos_Bool must_subst_params (sos_Param_List old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("must_subst_params");
TT (cfe_M, T_ENTER);
sos_Bool result = FALSE;
agg_iterate (old, sos_Param old_p)
{ sos_Type_name old_tn = old_p.get_type_name();
result = must_subst_type_name (old_tn, gpl, tnl, type_decls);
if (result) break;
}
agg_iterate_end (old, old_p);
TT (cfe_M, T_LEAVE);
return result;
}
LOCAL sos_Param_List subst_params (sos_Param_List old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("subst_params");
TT (cfe_M, T_ENTER);
sos_Param_List new_pl;
if (NOT must_subst_params (old, gpl, tnl, type_decls))
new_pl = old;
else
{ new_pl = sos_Param_List::create (cfe_cnt, FALSE);
agg_iterate (old, sos_Param old_p)
{ sos_Type_name old_tn = old_p.get_type_name();
sos_Type_name new_tn = subst_type_name (old_tn, gpl, tnl, type_decls);
#ifdef ATT
if (new_tn.operator==(old_tn))
#else
if (new_tn == old_tn)
#endif
new_pl.append (old_p);
else
{ sos_Param new_p = sos_Param::create (cfe_cnt);
new_p.set_name (old_p.get_name());
new_p.set_type_name (new_tn);
new_p.set_default_expr (old_p.get_default_expr());
new_p.set_is_ref (old_p.get_is_ref());
new_pl.append (new_p);
}
}
agg_iterate_end (old, old_p);
}
TT (cfe_M, T_LEAVE);
return new_pl;
}
LOCAL sos_Bool must_subst_type_name (sos_Type_name old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("must_subst_type_name");
TT (cfe_M, T_ENTER);
sos_Bool result;
if (old.has_type (sos_Generic_instantiation_type))
{ sos_Generic_instantiation gi = sos_Generic_instantiation::make(old);
sos_Type_name_List old_tnl = gi.get_gen_params();
result = must_subst_type_names (old_tnl, gpl, tnl, type_decls);
}
else if (old.has_type (sos_Type_with_params_type))
{ sos_Type_with_params twp = sos_Type_with_params::make(old);
sos_Type_name old_twpn = twp.get_type_name();
result = must_subst_type_name (old_twpn, gpl, tnl, type_decls);
}
else if (old.has_type (sos_Gen_param_type))
result = TRUE;
else
result = FALSE;
TT (cfe_M, T_LEAVE);
return result;
}
LOCAL sos_Type_name subst_type_name (sos_Type_name old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("subst_type_name");
TT (cfe_M, T_ENTER);
sos_Type_name new_tn;
if (old.has_type (sos_Generic_instantiation_type))
{ sos_Generic_instantiation gi = sos_Generic_instantiation::make(old);
sos_Type_name_List old_tnl = gi.get_gen_params();
sos_Type_name_List new_tnl =
subst_type_names (old_tnl, gpl, tnl, type_decls);
#ifdef ATT
if (new_tnl.operator==(old_tnl))
#else
if (new_tnl == old_tnl)
#endif
new_tn = old;
else
{ sos_Generic_instantiation new_gi =
sos_Generic_instantiation::create (cfe_cnt);
new_gi.set_gen (gi.get_gen());
new_gi.set_gen_params (new_tnl);
new_gi.set_instantiation (make_aux_class_type (new_gi, type_decls));
new_tn = new_gi;
}
}
else if (old.has_type (sos_Type_with_params_type))
{ sos_Type_with_params twp = sos_Type_with_params::make(old);
sos_Type_name old_twpn = twp.get_type_name();
sos_Type_name new_twpn =
subst_type_name (old_twpn, gpl, tnl, type_decls);
#ifdef ATT
if (new_twpn.operator==(old_twpn))
#else
if (new_twpn == old_twpn)
#endif
new_tn = old;
else
{ sos_Type_with_params new_twp =
sos_Type_with_params::create (cfe_cnt);
new_twp.set_type_name (new_twpn);
new_twp.set_params (twp.get_params());
new_tn = new_twp;
}
}
else if (old.has_type (sos_Gen_param_type))
new_tn = subst_actual (sos_Gen_param::make(old), gpl, tnl);
else
new_tn = old;
TT (cfe_M, T_LEAVE);
return new_tn;
}
LOCAL sos_Bool must_subst_type_names (sos_Type_name_List old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("must_subst_type_names");
TT (cfe_M, T_ENTER);
sos_Bool result = FALSE;
agg_iterate (old, sos_Type_name old_tn)
{ result = must_subst_type_name (old_tn, gpl, tnl, type_decls);
if (result) break;
}
agg_iterate_end (old, old_tn);
TT (cfe_M, T_LEAVE);
return result;
}
LOCAL sos_Type_name_List subst_type_names (sos_Type_name_List old,
sos_Gen_param_List gpl,
sos_Type_name_List tnl,
sos_Schema_type_List type_decls)
{
T_PROC ("subst_type_names");
TT (cfe_M, T_ENTER);
sos_Type_name_List new_tnl;
if (NOT must_subst_type_names (old, gpl, tnl, type_decls))
new_tnl = old;
else
{ new_tnl = sos_Type_name_List::create (cfe_cnt, FALSE);
agg_iterate (old, sos_Type_name old_tn)
{ new_tnl.append (subst_type_name (old_tn, gpl, tnl, type_decls));
}
agg_iterate_end (old, old_tn);
}
TT (cfe_M, T_LEAVE);
return new_tnl;
}
static sos_Schema_type *the_void_type;
// *************************************************************************
LOCAL sos_Schema_type cfe_get_void_type()
// *************************************************************************
{
T_PROC ("cfe_get_void_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_void_type)
result = *the_void_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("void").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (void_type);
#endif
the_void_type = new sos_Schema_type;
*the_void_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}
static sos_Schema_type *the_sos_Bool_type;
// *************************************************************************
LOCAL sos_Schema_type cfe_get_sos_Bool_type()
// *************************************************************************
{
T_PROC ("cfe_get_sos_Bool_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_sos_Bool_type)
result = *the_sos_Bool_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("sos_Bool").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (sos_Bool_type);
#endif
the_sos_Bool_type = new sos_Schema_type;
*the_sos_Bool_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}
static sos_Schema_type *the_sos_Eq_kind_type;
// *************************************************************************
LOCAL sos_Schema_type cfe_get_sos_Eq_kind_type()
// *************************************************************************
{
T_PROC ("cfe_get_sos_Eq_kind_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_sos_Eq_kind_type)
result = *the_sos_Eq_kind_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("sos_Eq_kind").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (sos_Eq_kind_type);
#endif
the_sos_Eq_kind_type = new sos_Schema_type;
*the_sos_Eq_kind_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}
static sos_Schema_type *the_sos_Int_type;
// *************************************************************************
LOCAL sos_Schema_type cfe_get_sos_Int_type()
// *************************************************************************
{
T_PROC ("cfe_get_sos_Int_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_sos_Int_type)
result = *the_sos_Int_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("sos_Int").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (sos_Int_type);
#endif
the_sos_Int_type = new sos_Schema_type;
*the_sos_Int_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}
static sos_Schema_type *the_container_type;
// *************************************************************************
LOCAL sos_Schema_type cfe_get_container_type()
// *************************************************************************
{
T_PROC ("cfe_get_container_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_container_type)
result = *the_container_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("sos_Container").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (sos_Container_type);
#endif
the_container_type = new sos_Schema_type;
*the_container_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}
static sos_Schema_type *the_object_type;
// *************************************************************************
EXPORT sos_Schema_type cfe_get_object_type()
// *************************************************************************
{
T_PROC ("cfe_get_object_type");
TT (cfe_H, T_ENTER);
sos_Schema_type result;
if (the_object_type)
result = *the_object_type;
else
{
#ifdef BOOT
result = cfe_schema.lookup_type (smg_String ("sos_Object").make_String (TEMP_CONTAINER));
#else
result = sos_Schema_type::make (sos_Object_type);
#endif
the_object_type = new sos_Schema_type;
*the_object_type = result;
}
TT (cfe_H, T_LEAVE);
return result;
}